<?php

namespace Apps\Weixin\Controllers;

use Apps\Acp\Models\User;
use Apps\Acp\Services\UserService;
use Apps\Common\Constant\CacheTimeoutConstant;
use Apps\Common\Constant\ExceptionConstant;
use Apps\Common\Controller\WeixinBaseController;
use Deyi\Functions\UtilFunction;

/**
 * Class CallbackController
 * @package Apps\Weixin\Controllers
 */
class CallbackController extends WeixinBaseController
{
    private function tryAgain($visitUrl, $timeOut = 500)
    {
        $errMsg = <<<EOF
微信授权出了点小问题,请刷新页面重试!<script>setTimeout(function(){location.href='{$visitUrl}';},{$timeOut});</script>
EOF;
        static::errorThrow($errMsg, ExceptionConstant::PAGE_ERROR);
    }

    public function notifyAction()
    {
        $code = $this->getParamValue('code', null, null, true);
        $state = $this->getParamValue('state', null, null, true);

        $jumpToUrl = $this->cookies->get(self::WX_VISIT_URL_COOKIE_KEY)->getValue();
        $jumpToUrl = $jumpToUrl ? $jumpToUrl : '/';

        $cacheKey = $code . '_' . UtilFunction::getClientIp() . '_' . $jumpToUrl;

        $cache = $this->getUrlDataCache($cacheKey);

        if (is_array($cache)) {
            $this->session->set(self::WX_SESSION_KEY, $cache['user']);
            $this->redirectToUrl($cache['url']);
        }

        $time = @$this->crypt->decryptBase64(hex2bin($state));

        if (!is_numeric($time) || $time > time()) {
            static::errorThrow('state错误');
        }

        $res = $this->getWeixinUserInfo($code);

        if (!$res) {
            $this->tryAgain($jumpToUrl, 150);
        }

        // 检查此用户是否在无一合集已经注册过
        $member = UserService::getInstance()->getOneByFieldCache('openid', $res->openid);

        if (!$member) {
            User::getInstance()->insertByFields(['nickname' => $res->nickname, 'avatar' => $res->headimgurl, 'openid' => $res->openid, 'dateline' => time()]);
            $res->uid = User::getInstance()->getLastId();
        } else {
            $res->uid = $member->id;
        }

        $this->session->set(self::WX_SESSION_KEY, $res);

        if ($jumpToUrl) {
            $cache = [
                'user' => $res,
                'url' => $jumpToUrl
            ];
            $this->setUrlDataCache($cache, CacheTimeoutConstant::LOCAL_CACHE, $cacheKey);
            $this->redirectToUrl($jumpToUrl);
        }
    }

    public function receiveAction()
    {
        static::$_logger->info(json_encode($_POST) . ' ' . json_encode($_GET));
    }
}